package com.baike.controller;

import com.baike.data.Result;
import com.baike.em.ConstantEnum;
import com.baike.entity.TbLabel;
import com.baike.entity.TbLessonLabel;
import com.baike.feign.SearchServiceFeign;
import com.baike.mapper.TbLabelMapper;
import com.baike.mapper.TbLessonLabelMapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.data.redis.core.BoundZSetOperations;
import org.springframework.data.redis.core.DefaultTypedTuple;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.*;

@RestController
@RequestMapping("recommend")
@RefreshScope
public class RecommendController {


    @Resource
    private RedisTemplate redisTemplate;
    @Resource
    private TbLessonLabelMapper lessonLabelMapper;
    @Resource
    private TbLabelMapper labelMapper;
    @Resource
    private SearchServiceFeign searchServiceFeign;

    //用户点击课程详情调用该方法记录标签
    @GetMapping
    @ApiOperation("用户标签记录接口")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "studentsId",value = "用户id",required = true,paramType = "query"),
            @ApiImplicitParam(name = "lessonId",value = "课程id",required = true,paramType = "query")
    })
    public Result hobbyRecommend(@RequestParam("studentsId")Integer studentsId,@RequestParam("lessonId")Integer lessonId) {
        //先查询该课程对应标签
        QueryWrapper<TbLessonLabel> wrapper = new QueryWrapper<>();
        wrapper.eq("lesson_id", lessonId);
        List<TbLessonLabel> list = lessonLabelMapper.selectList(wrapper);
        //判断redis中是否存在该课程标签
        for (TbLessonLabel label : list) {
            //判断用户是否是第一次访问课程,判断键中是否存在该成员
            if (redisTemplate.hasKey(studentsId+"-num") && redisTemplate.boundZSetOps(studentsId+"-num").rank(label.getLabelId()) != null){
                //zset分数+1
                redisTemplate.boundZSetOps(studentsId+"-num").incrementScore(label.getLabelId(),1);
            }else {//如果用户是第一次访问,就直接记录
                //key:用户id+num,value:标签id,score:1,该缓存负责统计各个标签浏览量
                redisTemplate.boundZSetOps(studentsId+"-num").add(label.getLabelId(),1);
            }
            //记录进最近访问缓存
            //key:用户id_time,value:标签id,score:时间戳,该缓存负责统计各个标签访问时间
            redisTemplate.boundZSetOps(studentsId+"-time").add(label.getLabelId(),System.currentTimeMillis());
        }
        return Result.build(ConstantEnum.SUCCESS);
    }


    //定向推荐,用户推荐接口
    @GetMapping("recommend")
    @ApiOperation("用户推荐栏位接口")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "studentsId",value = "用户id",required = false,paramType = "query"),
    })
    public Result getRecommend(@RequestParam(value = "studentsId",required = false)Long studentsId){
        //如果用户登录了,
        if (studentsId != null && redisTemplate.hasKey(studentsId)){
            //并且之前记录过兴趣,获取用户推荐缓存前三返回
            Set<DefaultTypedTuple<Integer>> set = redisTemplate.boundZSetOps(studentsId).reverseRangeWithScores(0, 3);
            String labelName = "";
            for (DefaultTypedTuple<Integer> recommendDTO : set) {
                TbLabel tbLabel = labelMapper.selectById(recommendDTO.getValue());
                labelName += tbLabel.getLabelName()+",";
            }
            //调用es接口查询标签对应的课程
            Result lessons = searchServiceFeign.getLessonLabelName(labelName, 1, 4);
            return Result.build(ConstantEnum.SUCCESS).setResult(lessons.getResult());
        }else {
            //如果用户没有登录
            //返回热门课程,
            List<TbLabel> labels = labelMapper.selectList(null);
            String labelName = "";
            for (int i = 0; i < 3; i++) {
                labelName += labels.get(i).getLabelName()+",";
            }
            //调用es查询课程
            Result result = searchServiceFeign.getLessonLabelName(labelName, 1, 4);
            return Result.build(ConstantEnum.SUCCESS).setResult(result.getResult());
        }
    }


    //测试查看redis数据接口
    @GetMapping("findRedis")
    @ApiOperation("用户标签记录查询接口")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "studentsId",value = "用户id",required = true,paramType = "query"),
    })
    public Result findRedis(@RequestParam("studentsId")Long studentsId) {
        //标签记录数查询
        Set num = redisTemplate.boundZSetOps(studentsId + "-num").reverseRangeWithScores(0, -1);
        //标签访问时间查询
        Set time = redisTemplate.boundZSetOps(studentsId + "-time").reverseRangeWithScores(0, -1);
        //定向推荐缓存查询
        Set recommend = redisTemplate.boundZSetOps(studentsId).reverseRangeWithScores(0, -1);
        Map map = new HashMap();
        map.put("num",num);
        map.put("time",time);
        map.put("recommend",recommend);
        return Result.build(ConstantEnum.SUCCESS).setResult(map);
    }


}
